package org.acghub.mtdb.xmlgen.visitor;

import org.acghub.mtdb.common.Bean;
import org.acghub.mtdb.common.Type;
import org.acghub.mtdb.common.Var;
import org.acghub.mtdb.common.Visitor;
import org.acghub.mtdb.common.type.TypeBaseCollection;
import org.acghub.mtdb.common.type.TypeBaseMap;
import org.acghub.mtdb.common.type.TypeBasePrimitives;
import org.acghub.mtdb.core.Logs;
import org.acghub.mtdb.core.Transaction;
import org.acghub.mtdb.util.StringUtil;

import java.io.PrintStream;

/**
 * @author zhouhe
 */
public class VarGetterVisitor implements Visitor {

    private final Var var;
    private final PrintStream ps;
    private final String prefix;

    public VarGetterVisitor(Var var, PrintStream ps, String prefix) {
        this.var = var;
        this.ps = ps;
        this.prefix = prefix;
    }

    private void makeSimple(Type type) {
        String method = "get" + StringUtil.upperFirstChar(var.getName());
        ps.println(prefix + "public " + type.javaInterfaceType() + " " + method + "() {");
        ps.printf(StringUtil.concat(prefix, StringUtil.TAB) + "this._verify_unsafe_(%s, %s);\n", StringUtil.quote(method), "true");
        ps.println(StringUtil.concat(prefix, StringUtil.TAB) + "return this." + var.getName() + ";");
        ps.println(prefix + "}");
    }

    private void makeContainer(Type type) {
        String typeName = type.getName();
        String method = "get" + StringUtil.upperFirstChar(var.getName());
        ps.println(prefix + "public " + type.javaInterfaceType() + " " + method + "() {");
        ps.printf(StringUtil.concat(prefix, StringUtil.TAB) + "if (%s.isActive()) {\n", Transaction.class.getName());
        String format = String.format("return %s.%s(this, %s, this.%s, this._verify_unsafe_(%s, %s));",
                Logs.class.getName(), typeName, StringUtil.quote(var.getName()), var.getName(), StringUtil.quote(method), "true");
        ps.println(StringUtil.concat(prefix, StringUtil.tab(2)) + format);
        ps.println(StringUtil.concat(prefix, StringUtil.TAB) + "} else {");
        ps.println(StringUtil.concat(prefix, StringUtil.tab(2)) + "return this." + var.getName() + ";");
        ps.println(StringUtil.concat(prefix, StringUtil.TAB) + "}");
        ps.println(prefix + "}");
    }

    @Override
    public void visit(TypeBasePrimitives type) {
        makeSimple(type);
    }

    @Override
    public void visit(TypeBaseCollection type) {
        makeContainer(type);
    }


    @Override
    public void visit(TypeBaseMap type) {
        makeContainer(type);
    }

    @Override
    public void visit(Bean bean) {
        makeSimple(bean);
    }
}
